package gemini.castor.ui.client.page.content.office.events.list;

import gemini.basic.model.Event;
import gemini.castor.ui.client.ServiceCatalog;
import gemini.castor.ui.client.mvp.callback.AbstractAsyncCallback;
import gemini.castor.ui.client.mvp.single.CastorWidgetDisplay;
import gemini.castor.ui.client.mvp.single.CastorWidgetPresenter;
import gemini.castor.ui.client.page.RootEvent;
import gemini.castor.ui.client.page.content.office.events.EventsEvent;
import gemini.castor.ui.client.page.content.office.events.EventsObject;
import gemini.castor.ui.client.page.content.office.events.widget.EventsTableEvent;
import gemini.castor.ui.client.page.content.office.events.widget.EventsTableHandler;
import gemini.castor.ui.client.page.content.office.events.widget.EventsTableWidget;
import gemini.castor.ui.client.utils.PlaceConstants;

import java.util.List;

import ch.elca.gwt.mvp.client.EventBus;
import ch.elca.gwt.mvp.client.place.Place;

import com.google.inject.Inject;

public class EventsListPresenter extends
		CastorWidgetPresenter<EventsListPresenter.Display> {

	@Inject
	public EventsListPresenter(Display display, EventBus globalEventBus) {
		super(display, globalEventBus);
	}

	public interface Display extends CastorWidgetDisplay {

		EventsTableWidget getEventsTableWidget();

		void initCustom();

		void showEvents(List<Event> events);

	}

	private String distributorCode;

	private List<Event> events;

	@Override
	public void setInputObject(Object ob) {
		if (ob instanceof EventsObject) {
			EventsObject eventOb = (EventsObject) ob;
			if (eventOb != null) {
				events = eventOb.getEvents();
			}
		} else {
			distributorCode = (String) ob;
		}
	}

	public static final Place PLACE = new Place(PlaceConstants.PLACE_EVENTS);

	private void registerEventHandler() {
		registerHandler(display.getEventsTableWidget().addEventsActionHandler(
				new EventsTableHandler() {

					@Override
					public void onAdd(EventsTableEvent event) {
						localEventBus.fireEvent(new EventsEvent(
								EventsEvent.ForwardType.NEW));
					}

					@Override
					public void onDelete(EventsTableEvent event) {
						eventBus.fireEvent(new RootEvent(RootEvent.ForwardType.MASK));
						ServiceCatalog.getEventService().deleteEvent(event.getEvent().getId(),
								new AbstractAsyncCallback<Void>() {

									@Override
									public void onSuccess(Void result) {
										eventBus.fireEvent(new RootEvent(
												RootEvent.ForwardType.UN_MASK));
										localEventBus.fireEvent(new EventsEvent(
												EventsEvent.ForwardType.BACK_TO_LIST));
									}
								});
					}

					@Override
					public void onEdit(EventsTableEvent event) {
						EventsEvent newEvent = new EventsEvent(
								EventsEvent.ForwardType.EDIT);
						newEvent.setEvent(event.getEvent());
						localEventBus.fireEvent(newEvent);

					}

				}));

		display.initCustom();
		display.showEvents(events);
	}

	@Override
	protected void onBind() {
		registerEventHandler();
		eventBus.fireEvent(new RootEvent(RootEvent.ForwardType.MASK));
		ServiceCatalog.getEventService().getEventByDistributorCode(
				distributorCode, new AbstractAsyncCallback<List<Event>>() {

					@Override
					public void onSuccess(List<Event> result) {
						eventBus.fireEvent(new RootEvent(
								RootEvent.ForwardType.UN_MASK));
						if (result != null && !result.isEmpty()) {
							display.initCustom();
							display.showEvents(result);
						}
					}
				});
	}

	protected void addNewEvent(final Event object) {
		ServiceCatalog.getEventService().saveOrUpdateEvent(object,
				new AbstractAsyncCallback<Event>() {

					@Override
					public void onSuccess(Event result) {
						eventBus.fireEvent(new RootEvent(
								RootEvent.ForwardType.UN_MASK));
						if (result != null) {
							events.add(result);
							display.showEvents(events);
							display.loadData();
						}
					}
				});

	}

	@Override
	public Place getPlace() {
		return PLACE;
	}

	@Override
	public void onUnbind() {
		events = null;
	}
}
